"""
ParamValuesTree.py --

This is second file of Dynamic mode window.

Date of creation: 2010-15-11

Copyright
Julian David Colorado, jd.colorado@upm.es
Universidad Politecnica de Madrid

See the file "license.terms" for information on usage and redistribution of this file, and for a
DISCLAIMER OF ALL WARRANTIES.
"""
import wx
import os, sys
from numpy import *
from systems import dcmotor


#global variables.

radstodeg = (180/pi)
degtorads = (pi/180)
FALSE = 0
TRUE = 1

#Windows
wintreewidth = 210

#Linux
lnxtreewidth = 295

#Control Tree Lists.
#Dynamic Model
bat_dynmodel_list				= [ "Humerus Mass:", "Radius Mass:", "Humerus Lenght:" ,"Radius Lenght:", "Gravity:" ]
bat_kinemodel_list				= [ "Lift Coeff:" ]
batwing_dynmodel_list			= [ "Mass:", "Inertia:", "Friction:", "Gravity:"]
batwing_kinemodel_list		= [ "Pend. 1 Length:", "Pend. 2 Length:" ]

#Motor Models
motor_1_list = [ "Ka:", "Ta:" ]
motor_2_list = [ "Rsma:", "rsma:",  "Lsma:",  "hsma:" ]
motor_3_list = [ "Rsma:", "rsma:",  "Lsma:",  "hsma:" ]

#controllers
controller_list = [ "Controller:", "Controller Order: ", "Control Step Time: ", "Control Switch Range: ","Swing Up:", "Swing Up Order: " ]


class ParamValuesTree( wx.TreeCtrl ):
	""" Ctrl Tree that stores the dynamic parameters values."""
	def __init__( self, parent, id):
		if (os.name=='nt'):
			wx.TreeCtrl.__init__(self, parent, id, wx.DefaultPosition, wx.Size(wintreewidth , 1200), wx.TR_LINES_AT_ROOT | wx.TR_EXTENDED | wx.TR_HIDE_ROOT | wx.TR_HAS_BUTTONS )
		else:
			wx.TreeCtrl.__init__(self, parent, id, wx.DefaultPosition, wx.Size(lnxtreewidth , 1200), wx.TR_LINES_AT_ROOT | wx.TR_EXTENDED | wx.TR_HIDE_ROOT | wx.TR_HAS_BUTTONS )

		self.root = self.AddRoot('Values')

		#Dynamic Model
		self.dynmodel		=self.AppendItem( self.root, 'Bat Model:')
		self.dynparam		=self.AppendItem( self.dynmodel, 'Dynamic Params:' )
		self.kineparam		=self.AppendItem( self.dynmodel, 'Aerodynamics Params:' )

		#Motor Model
		self.motormod = self.AppendItem(self.root, 'Actuation Model')
		#Control Model
		self.ctrlmod			= self.AppendItem(self.root, 'Controller Setup:')

		#ODE Solver
		self.integr = self.AppendItem(self.root, 'ODE Solver')
		self.integstep = self.AppendItem( self.integr, 'Step Time: %f ms' %0.0, wx.NewId())

		#Total simulation time
		self.time = self.AppendItem(self.root, 'Simulation Time: %f s' %0.0 )

		#Matlab file
		self.matlab = self.AppendItem(self.root, 'Matlab File:')
		self.x1 = self.AppendItem(self.matlab, 'X1: %d' %1)
		self.x2 = self.AppendItem(self.matlab, 'X2: %d' %2)
		self.dx1 = self.AppendItem(self.matlab, 'dX1: %d' %3)
		self.dx2 = self.AppendItem(self.matlab, 'dX2: %d' %4)

		#self.Expand( self.root )
		self.Centre()


	def UpdateMotor1Info( self, system ):
		self.motoritem = []    #motor model subtree list.
		"""This function updates the Motor1 Tree info"""
		for item in motor_1_list:
			self.motoritem.append (self.AppendItem(self.motormod, item))
		#motor model values
		self.SetItemText( self.motoritem[0], 'Ka: %f' %system.dcmotor.Ka )
		self.SetItemText( self.motoritem[1], 'Ta: %f' %system.dcmotor.Ta  )

	def UpdateMotor2Info( self, system ):
		"""This function updates the Motor2 Tree info"""
		self.motoritem = []    #motor model subtree list.
		for item in motor_2_list:
			self.motoritem.append (self.AppendItem(self.motormod, item))
		#motor model values
		self.SetItemText( self.motoritem[0], 'Rsma: %f m' %system.dcmotor.R )
		self.SetItemText( self.motoritem[1], 'rsma: %f m' %system.dcmotor.r  )
		self.SetItemText( self.motoritem[2], 'Lsma: %f' %system.dcmotor.Km )
		self.SetItemText( self.motoritem[3], 'hsma: %f' %system.dcmotor.Kg  )

	def UpdateMotor3Info( self, system ):
		"""This function updates the Motor3 Tree info"""
		self.motoritem = []    #motor model subtree list.
		for item in motor_3_list:
			self.motoritem.append (self.AppendItem(self.motormod, item))
		#motor model values
		self.SetItemText( self.motoritem[0], 'Rsma: %f m' %system.dcmotor.R )
		self.SetItemText( self.motoritem[1], 'rsma: %f m' %system.dcmotor.r  )
		self.SetItemText( self.motoritem[2], 'Lsma: %f' %system.dcmotor.Km )
		self.SetItemText( self.motoritem[3], 'hsma: %f' %system.dcmotor.Kg  )

	def UpdateMotorTreeInfo ( self, system, systemtype, motorname ):
		"""This function updates the Motors Model Values Tree info"""
		self.DeleteChildren( self.motormod )
		system.dcmotor = dcmotor.DCmotor( motorname )
		self.SetItemText( self.motormod, 'Dynamic Model: %s' %motorname )
		system.motor = motorname
		system.MakefileGenerated = FALSE
		if ( system.dcmotor.type == 'motor1'):
			self.UpdateMotor1Info( system )
		elif ( system.dcmotor.type == 'motor2'):
			self.UpdateMotor2Info( system )
		elif ( system.dcmotor.type == 'motor3'):
			self.UpdateMotor3Info( system )

	def UpdateControllerTreeInfo ( self, contnum ):
		"""This function updates the Controllers Tree info"""
		self.DeleteChildren( self.ctrlmod )
		self.controlitem = []

		if ( contnum == 2 ):
			for item in controller_list:
				self.controlitem.append (self.AppendItem(self.ctrlmod, item))

			self.SetItemText( self.controlitem[4], 'Swing Up:' )
			self.SetItemText( self.controlitem[5], 'Swing Up Order: %f' %0.0 )
			self.SetItemText( self.controlitem[0], 'Controller:')
			self.SetItemText( self.controlitem[1], 'Controller Order: %f' %0.0 )
			self.SetItemText( self.controlitem[2], 'Control Step Time: %f ms' %0.0 )
			self.SetItemText( self.controlitem[3], 'Control Switch Range: %.2f deg' %0.0 )

		elif ( contnum == 1):
			for item in controller_list[:3]:
				self.controlitem.append (self.AppendItem(self.ctrlmod, item))

			self.SetItemText( self.controlitem[0], 'Controller:' )
			self.SetItemText( self.controlitem[1], 'Controller Order: %f' %0.0 )
			self.SetItemText( self.controlitem[2], 'Control Step Time: %f ms' %0.0 )


	def UpdateBatTreeCtrlInfo ( self, system ):
		"""This function updates the Bat's Param Values Tree info"""

		#Updating Dynamic Model Subtree.
		for item in bat_dynmodel_list:
			self.dynitem.append (self.AppendItem(self.dynparam, item))
		for item in bat_kinemodel_list:
			self.kineitem.append(self.AppendItem(self.kineparam, item))
		#Updating Motor Model Subtree.
		if ( system.dcmotor.type == 'motor2'):
			self.UpdateMotor2Info(system )

		self.UpdateControllerTreeInfo (system.ctrlnum)

		#updating subtree values.
		#dynamic params.
		#self.SetItemText( self.dynitem[0], 'body Mass: %f Kg' %system.Mb  )
		self.SetItemText( self.dynitem[0], 'Humerus Mass: %f Kg' %system.M  )
		self.SetItemText( self.dynitem[1], 'Radius Mass: %.4f Kg' %system.m  )
		self.SetItemText( self.dynitem[2], 'Humerus Lenght: %f' %system.K  )
		self.SetItemText( self.dynitem[3], 'Radius Lenght: %.3f' %system.p  )
		self.SetItemText( self.dynitem[4], 'Gravity: %f m/s^2' %system.grav  )
		#kinematic params.
		self.SetItemText( self.kineitem[0], 'Lift Coeff: %f m' %system.PendLength  )

	def UpdateBatwingTreeCtrlInfo ( self, system ):
		""" This function updates the batwing Values Tree associated info"""

		#Updating Dynamic Model Subtree.
		for item in batwing_dynmodel_list:
			self.dynitem.append (self.AppendItem(self.dynparam, item))
		for item in batwing_kinemodel_list:
			self.kineitem.append(self.AppendItem(self.kineparam, item))
		#Updating Motor Model Subtree.
		if ( system.dcmotor.type == 'motor1'):
			self.UpdateMotor1Info( system )

		self.UpdateControllerTreeInfo (system.ctrlnum)

		#updating subtree values.
		#dynamic params.
		self.SetItemText( self.dynitem[0], 'Mass: %f Kg' %system.m  )
		self.SetItemText( self.dynitem[1], 'Inertia: %f Kg.m^2' %system.Pend2Ine  )
		self.SetItemText( self.dynitem[2], 'Friction: %f' %system.Pend2fric )
		self.SetItemText( self.dynitem[3], 'Gravity: %f m/s^2' %system.grav  )
		#kinematic params.
		self.SetItemText( self.kineitem[0], 'Pend. 1 Length: %f m' %system.Pend1Length  )
		self.SetItemText( self.kineitem[1], 'Pend. 2 Length: %f m' %system.Pend2Length  )

	def UpdateTreeCtrlInfo( self, system ):
		""" This function updates the Param Values Tree associated info"""

		#Disasociate subtrees info.
		self.DeleteChildren( self.dynparam )
		self.DeleteChildren( self.kineparam )
		self.DeleteChildren( self.motormod )
		self.DeleteChildren( self.ctrlmod )
		#Empty list info.
		self.dynitem =  []       #dynamic params. subtree list.
		self.kineitem = []       #kinematic params. subtree list
		self.controlitem=[]		#Controller params subtree list.

		#Updating Dynmodel
		self.SetItemText( self.dynmodel, 'Bat Model: %s' %system.dynmodel )

		#Updating Motor Model
		self.SetItemText( self.motormod, 'Actuation Model: %s' %system.motor )
		if ( system.type == 'bat'):
			self.UpdateBatTreeCtrlInfo ( system )
		elif ( system.type == 'batwing'):
			self.UpdateBatwingTreeCtrlInfo ( system )

		#Updating Controller Subtree

		if(system.ctrlnum>0):
			#Controller order
			self.SetItemText( self.controlitem[0], 'Controller: %s' %system.control1  )
			#Controller order
			self.SetItemText( self.controlitem[1], 'Controller Order: %.5f' %system.ctrlorder  )
			#Control step time
			self.SetItemText( self.controlitem[2], 'Control Step Time: %f ms' %system.ctrlstep  )
		if(system.ctrlnum==2):
			#Controller switch range
			self.SetItemText( self.controlitem[3], 'Control Switch Range: %.2f deg' %(system.range*radstodeg) )
			#Swing up
			self.SetItemText( self.controlitem[4], 'Swing Up: %s' %system.control2  )
			#Swing up order
			self.SetItemText( self.controlitem[5], 'Swing Up Order: %f' %system.swinguporder  )

		#ODE Solver
		self.SetItemText( self.integr, 'ODE Solver: %s' %system.odesolver )
		#Integrator step time
		self.SetItemText( self.integstep, 'Step Time: %f ms' %system.integstep )
		#Total simulation time
		self.SetItemText( self.time, 'Simulation Time: %f s' %system.finaltime )
